﻿using System;
using System.Collections.Generic;
using NCMIS.ObjectModel.MetaData;

namespace NCMIS.Produce
{
    public static class Repository
    {
        private static Dictionary<string, PropertyDefinition> propertyDefinitions = new Dictionary<string, PropertyDefinition>
        {
            //
            // cmis:allowedChildObjectTypeIds    The IDs of the set of Object-types that can be created, moved or filed into this folder.
            //
            {
                CmisPropertyDefinitionId.AllowedChildObjectTypeIds, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.AllowedChildObjectTypeIds,
                    Inherited = false,
                    Required = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Multi,
                    Updatability = Updatability.Readonly,
                    QueryName = CmisPropertyDefinitionId.AllowedChildObjectTypeIds,
                    // Choices = N/A
                    // OpenChoice = N/A
                    // Repository specific
                    LocalName = "allowedChildObjectTypeIds",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Allowed Child Object Type IDs",
                    Description = "The IDs of the set of Object-types that can be created, moved or filed into this folder",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:baseTypeId    Id of the base object-type for the object.
            //
            {
                CmisPropertyDefinitionId.BaseTypeId, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.BaseTypeId,
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    QueryName = CmisPropertyDefinitionId.BaseTypeId,
                    // Choices = N/A
                    // OpenChoice = N/A
                    // Repository specific
                    LocalName = "baseTypeId",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Base Type ID",
                    Description = "The ID of the object base type",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:changeToken    Opaque token used for optimistic locking and concurrency checking.
            //
            {
                CmisPropertyDefinitionId.ChangeToken, new PropertyStringDefinition()
                {
                    // CMIS Specific
                    Id = CmisPropertyDefinitionId.ChangeToken,
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.ChangeToken,
                    // Repository specific
                    LocalName = "changeToken",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Change Token",
                    Description = "Token used for optimistic locking and concurrency checking",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:checkinComment
            //
            {
                "cmis:checkinComment", new PropertyStringDefinition()
                {
                    Id = "cmis:checkinComment",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:contentStreamId    Id of the stream.
            //
            {
                "cmis:contentStreamId", new PropertyIdDefinition()
                {
                    Id = "cmis:contentStreamId",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:contentStreamFileName    File name of the Content Stream.
            //
            {
                "cmis:contentStreamFileName", new PropertyStringDefinition()
                {
                    Id = "cmis:contentStreamFileName",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single
                }
            },
            //
            // cmis:contentStreamLength    Length of the content stream (in bytes).
            //
            {
                "cmis:contentStreamLength", new PropertyIntegerDefinition()
                {
                    Id = "cmis:contentStreamLength",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Integer,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:contentStreamMimeType    MIME type of the Content Stream.
            //
            {
                "cmis:contentStreamMimeType", new PropertyStringDefinition()
                {
                    Id = "cmis:contentStreamMimeType",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:createdBy    User who created the object.
            //
            {
                CmisPropertyDefinitionId.CreatedBy, new PropertyStringDefinition()
                {
                    Id = CmisPropertyDefinitionId.CreatedBy,
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    Queryable = true,
                    Orderable = true,
                    QueryName = CmisPropertyDefinitionId.CreatedBy,
                    // Repository specific
                    LocalName = "createdBy",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Created By",
                    Description = "The user who created this object",
                    OpenChoice = false
                }
            },
            //
            // cmis:creationDate    DateTime when the object was created.
            //
            {
                CmisPropertyDefinitionId.CreationDate, new PropertyDateTimeDefinition()
                {
                    Id = CmisPropertyDefinitionId.CreationDate,
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Datetime,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    Queryable = true,
                    Orderable = true,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.CreationDate,
                    // Repository specific
                    LocalName = "creationDate",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Creation Date",
                    Description = "DateTime when the object was created"
                }
            },
            //
            // cmis:isImutable    True if the repository must throw an error at any attempt to update or delete the object.
            //
            {
                "cmis:isImmutable", new PropertyBooleanDefinition()
                {
                    Id = "cmis:isImmutable",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Boolean,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:isLatestMajorVersion
            //
            {
                "cmis:isLatestMajorVersion", new PropertyBooleanDefinition()
                {
                    Id = "cmis:isLatestMajorVersion",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Boolean,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:isLatestVersion
            //
            {
                "cmis:isLatestVersion", new PropertyBooleanDefinition()
                {
                    Id = "cmis:isLatestVersion",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Boolean,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:isMajorVersion
            //
            {
                "cmis:isMajorVersion", new PropertyBooleanDefinition()
                {
                    Id = "cmis:isMajorVersion",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Boolean,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            {
                "cmis:isVersionSeriesCheckedOut", new PropertyBooleanDefinition()
                {
                    Id = "cmis:isVersionSeriesCheckedOut",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Boolean,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:lastModificationDate    DateTime when the object was last modified.
            //
            {
                "cmis:lastModificationDate", new PropertyDateTimeDefinition()
                {
                    Id = "cmis:lastModificationDate",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Datetime,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    Queryable = true,
                    Orderable = true,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.LastModificationDate,
                    // Repository specific
                    LocalName = "lastModificationDate",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Last Modification Date",
                    Description = "DateTime when the object was last modified"
                }
            },
            //
            // cmis:lastModifiedBy    User who last modified the object.
            //
            {
                "cmis:lastModifiedBy", new PropertyStringDefinition()
                {
                    Id = "cmis:lastModifiedBy",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    Queryable = true,
                    Orderable = true,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.LastModifiedBy,
                    // Repository specific
                    LocalName = "lastModifiedBy",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Last Modified By",
                    Description = "The user who last modified the object",
                }
            },
            //
            // cmis:name    Name of the object.
            //
            {
                CmisPropertyDefinitionId.Name, new PropertyStringDefinition()
                {
                    Id = "cmis:name",
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Required = true,
                    QueryName = CmisPropertyDefinitionId.Name,
                    // Repository specific
                    LocalName = "name",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Name",
                    Description = "Name of the object",
                    Updatability = Updatability.ReadWrite,
                    Queryable = true,
                    Orderable = true,
                    //Choices = N/A
                    //OpenChoice = N/A
                }
            },
            //
            // cmis:objectId    ID of the object.
            //
            {
                CmisPropertyDefinitionId.ObjectId, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.ObjectId,
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    QueryName = CmisPropertyDefinitionId.ObjectId,
                    // Choices = N/A
                    // OpenChoice = N/A
                    // Repository specific
                    LocalName = "objectId",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Object ID",
                    Description = "The unique object ID",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:objectTypeId    Id of the object's type.
            //
            {
                CmisPropertyDefinitionId.ObjectTypeId, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.ObjectTypeId,
                    Required = true,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.OnCreate,
                    QueryName = CmisPropertyDefinitionId.ObjectTypeId,
                    // Choices = N/A
                    // OpenChoice = N/A
                    // Repository specific
                    LocalName = "objectTypeId",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Object Type ID",
                    Description = "The ID of the object type",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:parentId    The ID of parent folder of the folder.
            //
            {
                CmisPropertyDefinitionId.ParentId, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.ParentId,
                    Inherited = false,
                    Required = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly,
                    QueryName = CmisPropertyDefinitionId.ParentId,
                    // Choices = N/A
                    // OpenChoice = N/A
                    // Repository specific
                    LocalName = "parentId",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Parent ID",
                    Description = "The ID of parent folder of the folder",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:path    The fully qualified path to this folder.
            //
            {
                CmisPropertyDefinitionId.Path, new PropertyStringDefinition()
                {
                    Id = CmisPropertyDefinitionId.Path,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Required = false,
                    Updatability = Updatability.Readonly,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.Path,
                    // Repository specific
                    LocalName = "path",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Path",
                    Description = "The fully qualified path to this folder",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:policyText    The user-friendly description of the policy.
            //
            {
                CmisPropertyDefinitionId.PolicyText, new PropertyStringDefinition()
                {
                    Id = CmisPropertyDefinitionId.PolicyText,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Required = true,
                    Updatability = Updatability.Readonly,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.PolicyText,
                    // Repository specific
                    LocalName = "policyText",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Policy Text",
                    Description = "The user-friendly description of the policy",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:sourceId    The ID of the source object of the relationship.
            //
            {
                CmisPropertyDefinitionId.SourceId, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.SourceId,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Required = true,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.SourceId,
                    // Repository specific
                    Updatability = Updatability.Readonly,
                    LocalName = "sourceId",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Source ID",
                    Description = "The ID of the source object of the relationship",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:targetId     The ID of the target object of the relationship.
            //
            {
                CmisPropertyDefinitionId.TargetId, new PropertyIdDefinition()
                {
                    Id = CmisPropertyDefinitionId.TargetId,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Required = true,
                    // Choices = N/A
                    // OpenChoice = N/A
                    QueryName = CmisPropertyDefinitionId.TargetId,
                    // Repository specific
                    Updatability = Updatability.Readonly,
                    LocalName = "targetId",
                    LocalNamespace = "http://www.episerver.com/model/cmis/1.0/cd04",
                    DisplayName = "Target ID",
                    Description = "The ID of the target object of the relationship",
                    Queryable = true,
                    Orderable = true,
                }
            },
            //
            // cmis:versionLabel
            //
            {
                "cmis:versionLabel", new PropertyStringDefinition()
                {
                    Id = "cmis:versionLabel",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:versionSeriesCheckedOut
            //
            {
                "cmis:versionSeriesCheckedOut", new PropertyBooleanDefinition()
                {
                    Id = "cmis:versionSeriesCheckedOut",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Boolean,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:versionSeriesCheckedOutBy
            //
            {
                "cmis:versionSeriesCheckedOutBy", new PropertyStringDefinition()
                {
                    Id = "cmis:versionSeriesCheckedOutBy",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.String,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:versionSeriesCheckedOutId
            //
            {
                "cmis:versionSeriesCheckedOutId", new PropertyIdDefinition()
                {
                    Id = "cmis:versionSeriesCheckedOutId",
                    Required = false,
                    Inherited = false,
                    PropertyType = CmisPropertyType.Id,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            },
            //
            // cmis:versionSeriesId
            //
            {
                "cmis:versionSeriesId", new PropertyIdDefinition()
                {
                    Id = "cmis:versionSeriesId",
                    Required = false,
                    Inherited = false,
                    Cardinality = Cardinality.Single,
                    Updatability = Updatability.Readonly
                }
            }
        };

        public static PropertyDefinition GetPropertyDefinition(string propertyDefinitionId)
        {
            PropertyDefinition result = null;
            if (!propertyDefinitions.TryGetValue(propertyDefinitionId, out result))
            {
                throw new Exception(String.Format("PropertyDefinitionId \"{0}\" was not found.", propertyDefinitionId));
            }
            return result;
        }
    }
}
